// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#include "pch.h"

#include "ContentControlViewManager.h"
#include <Views/ShadowNodeBase.h>

#include <Utils/ValueUtils.h>

#include <winrt/Windows.UI.Xaml.Controls.h>

namespace winrt {
  using namespace Windows::Foundation;
  using namespace Windows::UI;
  using namespace Windows::UI::Xaml;
  using namespace Windows::UI::Xaml::Controls;
  using namespace Windows::UI::Xaml::Media;
}

namespace react { namespace uwp { namespace polyester {

class ContentControlShadowNode : public ShadowNodeBase
{
  using Super = ShadowNodeBase;
public:
  ContentControlShadowNode() = default;
  void createView() override;
  bool IsExternalLayoutDirty() const override { return m_paddingDirty; }
  void DoExtraLayoutPrep(YGNodeRef yogaNode) override;

private:
  bool m_paddingDirty = false;
};

void ContentControlShadowNode::DoExtraLayoutPrep(YGNodeRef yogaNode)
{
  if (!m_paddingDirty)
    return;

  m_paddingDirty = false;

  auto contentControl = GetView().try_as<winrt::ContentControl>();
  auto padding = contentControl.Padding();

  YGNodeStyleSetPadding(yogaNode, YGEdgeLeft, static_cast<float>(padding.Left));
  YGNodeStyleSetPadding(yogaNode, YGEdgeTop, static_cast<float>(padding.Top));
  YGNodeStyleSetPadding(yogaNode, YGEdgeRight, static_cast<float>(padding.Right));
  YGNodeStyleSetPadding(yogaNode, YGEdgeBottom, static_cast<float>(padding.Bottom));
}


void ContentControlShadowNode::createView()
{
  Super::createView();

  auto obj = GetView().try_as<winrt::DependencyObject>();
  if (obj != nullptr)
  {
    // Button styles may have padding Yoga is not aware of
    obj.RegisterPropertyChangedCallback(winrt::Windows::UI::Xaml::Controls::Control::PaddingProperty(), [this](winrt::Windows::UI::Xaml::DependencyObject const& sender, winrt::Windows::UI::Xaml::DependencyProperty const& dp)
    {
      m_paddingDirty = true;
    });
  }
}

ContentControlViewManager::ContentControlViewManager(const std::shared_ptr<IReactInstance>& reactInstance)
  : Super(reactInstance)
{
}

facebook::react::ShadowNode* ContentControlViewManager::createShadow() const
{
  return new ContentControlShadowNode();
}

void ContentControlViewManager::AddView(XamlView parent, XamlView child, int64_t index)
{
  // ContentControl holds a single child, so should never insert after
  if (index != 0)
  {
    // ASSERT: Currently considering any index other than 0 as ignorable since ContentControl can only have a single child.
    assert(false);
    return;
  }

  auto contentControl(parent.as<winrt::ContentControl>());
  if (contentControl != nullptr)
    contentControl.Content(child.as<winrt::IInspectable>());
}

void ContentControlViewManager::RemoveAllChildren(XamlView parent)
{
  auto contentControl(parent.as<winrt::ContentControl>());
  if (contentControl != nullptr)
    contentControl.Content(nullptr);
}

void ContentControlViewManager::RemoveChildAt(XamlView parent, int64_t index)
{
  if (index != 0)
    return;

  auto contentControl(parent.as<winrt::ContentControl>());
  if (contentControl != nullptr)
    contentControl.Content(nullptr);
}

}}}
